package com.fy.fyspace.controller;

import com.fy.fyspace.common.result.R;
import com.fy.fyspace.common.utils.CreateImageCode;
import com.fy.fyspace.common.utils.EmailCodeSend;
import com.fy.fyspace.common.utils.StringTools;
import com.fy.fyspace.constant.KeysConstant;
import com.fy.fyspace.constant.ResultMessageConstant;
import com.fy.fyspace.ex.ConditionException;
import com.fy.fyspace.ex.handler.ExHandler;
import com.fy.fyspace.mapper.UserFeedBackMapper;
import com.fy.fyspace.model.dto.file.UploadVedioDTO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.messaging.MessagingException;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.concurrent.TimeUnit;

import static com.fy.fyspace.common.result.R.ok;
import static com.fy.fyspace.constant.KeysConstant.CHECK_CODE;

@Slf4j
@Api(tags = "通用接口模块")
@RestController
public class CommonController {

    @Autowired
    private JavaMailSender javaMailSender;

    @Autowired
    private EmailCodeSend emailCodeSend;

    @Autowired
    private UserFeedBackMapper userFeedBackMapper;

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 图形验证码生成
     *
     * @param response
     * @param httpSession
     * @throws IOException
     */
    @ApiOperation(value = "生成验证码", notes = "生成验证码")
    @GetMapping("/checkCode")
    public void checkCode(HttpServletResponse response, HttpSession httpSession) throws IOException {
        CreateImageCode vCode = new CreateImageCode(120, 38, 4, 12);
        response.setHeader("Pragma", "no-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expires", 0);
        response.setContentType("image/jpeg");
        String code = vCode.getCode();

        httpSession.removeAttribute(CHECK_CODE);

        httpSession.setAttribute(CHECK_CODE, code);
        httpSession.setMaxInactiveInterval(60);

        vCode.write(response.getOutputStream());
        log.info("生成验证码图片成功，验证码: {}", code);
    }

    /***
     * 发送验证码
     *
     * @param httpSession
     * @param checkCode
     * @return
     */
    @ApiOperation(value = "发送验证码", notes = "发送验证码")
    @PostMapping("/sendCode")
    public R sendEmailCode(HttpSession httpSession, @RequestParam("checkCode") String checkCode) {
        log.info("ll:{}", httpSession.getAttribute(CHECK_CODE), checkCode);
        if (checkCode.equalsIgnoreCase((String) httpSession.getAttribute(CHECK_CODE))) {
            httpSession.removeAttribute(CHECK_CODE);
            return ok();
        } else {
            httpSession.removeAttribute(CHECK_CODE);
            ExHandler.throwIf(ResultMessageConstant.CAPTCHA_ERROR);
            return ok();
        }
    }

    /**
     * 发送邮箱验证码
     * @param httpSession
     * @param email
     * @param checkCode
     * @return
     */
    @PostMapping("/sendEmailCode")
    @ApiOperation(value = "发送邮箱验证码", notes = "发送邮箱验证码")
    public R sendEmailCode(HttpSession httpSession, String email, @RequestParam("checkCode") String checkCode) {
        String sessionCode = (String) httpSession.getAttribute(KeysConstant.CHECK_CODE);
        log.info("本地和前端验证码:{}，{}", sessionCode, checkCode);

        if (checkCode.equalsIgnoreCase(sessionCode)) {
            String redisKey = KeysConstant.CHECK_CODE_EMAIL + email;
            String existingCode = stringRedisTemplate.opsForValue().get(redisKey);

            if (existingCode != null) {
                // 获取剩余过期时间（秒）
                Long expireTime = stringRedisTemplate.getExpire(redisKey, TimeUnit.SECONDS);
                if (expireTime != null && expireTime > 0) {
                    throw new ConditionException(String.format("操作过于频繁，请在%d秒后再试", expireTime));
                }
            }

            httpSession.removeAttribute(KeysConstant.CHECK_CODE);
            String code = StringTools.getRandomNumber(6);
            log.info("邮箱验证码为:{}", code);

            try {
                javaMailSender.send(emailCodeSend.packageMessage(email, code, 300));

                httpSession.setAttribute(KeysConstant.CHECK_CODE_EMAIL, code);
                httpSession.setMaxInactiveInterval(300);
                
                stringRedisTemplate.opsForValue().set(redisKey, code, 60, TimeUnit.SECONDS);
                return ok();
            } catch (MessagingException e) {
                log.error("邮件发送失败", e);
                throw new RuntimeException("邮件发送失败: " + e.getMessage());
            } catch (javax.mail.MessagingException e) {
                throw new RuntimeException(e);
            }
        } else {
            httpSession.removeAttribute(KeysConstant.CHECK_CODE);
            throw new ConditionException(ResultMessageConstant.CAPTCHA_ERROR);
        }
    }

    @PostMapping("/vedio/upload")
    public R uploadVedio(UploadVedioDTO uploadVedioDTO){
        log.info("上传视频:{}", uploadVedioDTO.getChunkIndex());
        // 模拟线程休眠1秒
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        return ok();
    }
}
